home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------
-
- AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
- Mail Service Access Module
-
- written by Steve Falkenburg-- MacDTS
- ©1991-1993 Apple Computer, Inc.
-
- --------------
- change history
- --------------
-
- SJF 02/19/93 update for beta build b1
- SJF 10/29/92 update to a11 a11
- SJF 06/08/92 update to a8 a8
- SJF 02/15/92 first working version a4.5
- SJF 10/16/91 initial coding a3
-
- ---------------------------------------------------------------------*/
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __OCE__
- #include <OCE.h>
- #endif
-
- #ifndef __OCEMAIL__
- #include <OCEMail.h>
- #endif
-
- #include <string.h>
-
- #include "const.h"
- #include "gwerrors.h"
- #include "mytypes.h"
- #include "globals.h"
- #include "utils.h"
- #include "spoolsystem.h"
- #include "gatewaystuff.h"
- #include "smtp.protocol.h"
- #include "convertaddress.h"
- #include "parser.h"
- #include "network.h"
-
- #include "spooltoexternal.h"
-
- #define kMaxMsgSize 64000
- #define kBCCBlockSize 2048
-
- #define kFromHeader "From: "
- #define kToHeader "To: "
- #define kCCHeader "Cc: "
- #define kBCCHeader "Bcc: "
- #define kSubjectHeader "Subject: "
- #define kAddressDelimiter ", "
-
- OSErr SpoolToExternalGW(FSSpec *spoolSpec,SlotSpec *slotSpec)
- {
- unsigned long smtpServerAddress;
- OSErr err;
- char tmpString[256];
- char bccBlock[256];
- char fromAddr[256];
- char *messageHeader;
- unsigned long tmpLen;
- RString tmpRString;
- char packedRecip[kMaxRecipSize];
- short recipIndex;
- Boolean hasRecipient;
-
- err = InitRemoteNetStuff();
- if (err!=noErr)
- return err;
-
- // allocate memory
-
- messageHeader = (char *)NewPtrChk(kMaxMsgSize);
- if (MemError()!=noErr) {
- return BailOnSend(MemError(),nil);
- }
- messageHeader[0] = 0;
-
- // get IP address of SMTP server
-
- err = ConvertStringToAddr(slotSpec->specInfo.smtpServer,&smtpServerAddress);
- if (err!=noErr) {
- return BailOnSend(kInvalidSMTPServer,messageHeader);
- }
-
- // build from address (from POP account)
-
- strcpy(fromAddr,slotSpec->dirIdentity.userName);
- strcat(fromAddr,"@");
- strcat(fromAddr,slotSpec->specInfo.popServer);
- strcpy(messageHeader,kFromHeader);
- strcat(messageHeader,fromAddr);
- strcat(messageHeader,kCRStr);
-
- // build to address
-
- hasRecipient = false;
- strcat(messageHeader,kToHeader);
- for (err=noErr,recipIndex=0; err==noErr; recipIndex++) {
- tmpLen = kMaxRecipSize;
- err = GetFromSpool(spoolSpec,kToType,kAddrCreator,recipIndex,(Ptr)packedRecip,&tmpLen,0);
- if (err==noErr) {
- if (TranslateAddress((OCEPackedRecipient *)packedRecip,tmpString)) {
- strcat(messageHeader,tmpString);
- strcat(messageHeader,kAddressDelimiter);
- hasRecipient = true;
- }
- }
- }
- if (hasRecipient) {
- messageHeader[strlen(messageHeader)-strlen(kAddressDelimiter)] = 0;
- strcat(messageHeader,kCRStr);
- }
- else {
- messageHeader[strlen(messageHeader)-strlen(kToHeader)] = 0;
- }
-
- // build cc address
-
- hasRecipient = false;
- strcat(messageHeader,kCCHeader);
- for (err=noErr,recipIndex=0; err==noErr; recipIndex++) {
- tmpLen = kMaxRecipSize;
- err = GetFromSpool(spoolSpec,kCCType,kAddrCreator,recipIndex,(Ptr)packedRecip,&tmpLen,0);
- if (err==noErr) {
- if (TranslateAddress((OCEPackedRecipient *)packedRecip,tmpString)) {
- strcat(messageHeader,tmpString);
- strcat(messageHeader,kAddressDelimiter);
- hasRecipient = true;
- }
- }
- }
- if (hasRecipient) {
- messageHeader[strlen(messageHeader)-strlen(kAddressDelimiter)] = 0;
- strcat(messageHeader,kCRStr);
- }
- else {
- messageHeader[strlen(messageHeader)-strlen(kCCHeader)] = 0;
- }
-
- // build bcc address (and store in separate string)
-
- hasRecipient = false;
- strcpy(bccBlock,kBCCHeader);
- for (err=noErr,recipIndex=0; err==noErr; recipIndex++) {
- tmpLen = kMaxRecipSize;
- err = GetFromSpool(spoolSpec,kBCCType,kAddrCreator,recipIndex,(Ptr)packedRecip,&tmpLen,0);
- if (err==noErr) {
- if (TranslateAddress((OCEPackedRecipient *)packedRecip,tmpString)) {
- strcat(bccBlock,tmpString);
- strcat(bccBlock,kAddressDelimiter);
- hasRecipient = true;
- }
- }
- }
- if (hasRecipient) {
- messageHeader[strlen(messageHeader)-strlen(kAddressDelimiter)] = 0;
- strcat(bccBlock,kCRStr);
- }
-
- // build subject
-
- strcat(messageHeader,kSubjectHeader);
- tmpLen = sizeof(RString);
- err = GetFromSpool(spoolSpec,kSubjectType,kAttribCreator,0,(Ptr)&tmpRString,&tmpLen,0);
- if (err==noErr) {
- r2cString(&tmpRString,tmpString);
- }
- else
- strcpy(tmpString,"<none>");
- strcat(messageHeader,tmpString);
- strcat(messageHeader,kCRStr);
- strcat(messageHeader,kCRStr);
-
- // spool message content from AOCE blocks into a single raw text block
-
- err = SpoolBodyFromAOCEToRaw(spoolSpec);
- if (err!=noErr)
- return err;
-
- err = SendSMTP(messageHeader,spoolSpec,bccBlock,fromAddr,smtpServerAddress);
- if (err!=noErr) {
- return BailOnSend(kInvalidSMTPServer,messageHeader);
- }
-
- DisposPtrChk(messageHeader);
- return noErr;
- }
-
-
- OSErr BailOnSend(OSErr err,Ptr messageBlock)
- {
- if (messageBlock)
- DisposPtrChk(messageBlock);
-
- return err;
- }
-
-
- Boolean TranslateAddress(OCEPackedRecipient *pRecip,char *unixRecip)
- {
- OCERecipient rcpt;
- RecordID entitySpecifier;
- OSType recipType;
- RString recipRStr;
-
- OCEUnpackDSSpec((PackedDSSpec*)pRecip,&rcpt,&entitySpecifier);
- recipType = rcpt.extensionType;
- switch (recipType) {
- case kPopAddrType:
- BlockMove(rcpt.extensionValue,&recipRStr,rcpt.extensionSize); // should probably do some range check
- r2cString(&recipRStr,unixRecip);
- break;
- default: // punt on string representation of aoce addresses for now
- return false;
- break;
- }
- return true;
- }
-
-
- /* translates a message from AOCE blocks into one large text block for sending over SMTP */
-
- OSErr SpoolBodyFromAOCEToRaw(FSSpec *spoolSpec)
- {
- OSErr err;
- Ptr bodyBuffer;
- unsigned long blockIndex,contentTypeIndex,rawContentLength,bufferLen;
- char *lfBuffer,*removeTerm;
- OSType contentTypes[kNumContentTypes] = {kTextContent,kPictContent,kSoundContent,
- kStyledTextContent,kMovieContent};
-
- bodyBuffer = NewPtrChk(kMaxBufferSize);
- if (MemError()!=noErr)
- return MemError();
-
- // index through all of the blocks, looking for each content type at each index
- // continue until we don't find any content at a particular index
-
- rawContentLength = 0;
-
- for (blockIndex=0,err=noErr; err==noErr; blockIndex++) {
- err = -1;
- for (contentTypeIndex=0; (err!=noErr) && (contentTypeIndex<kNumContentTypes); contentTypeIndex++) {
- err = GetSpoolLength(spoolSpec,contentTypes[contentTypeIndex],kContentCreator,blockIndex,&bufferLen);
- if (err==noErr) {
- switch (contentTypes[contentTypeIndex]) {
- case kTextContent:
- AddTextContent(spoolSpec,blockIndex,bodyBuffer,kMaxBufferSize,&rawContentLength);
- break;
- case kPictContent:
- AddPictContent(spoolSpec,blockIndex,bodyBuffer,kMaxBufferSize,&rawContentLength);
- break;
- case kSoundContent:
- AddSoundContent(spoolSpec,blockIndex,bodyBuffer,kMaxBufferSize,&rawContentLength);
- break;
- case kStyledTextContent:
- AddStyledTextContent(spoolSpec,blockIndex,bodyBuffer,kMaxBufferSize,&rawContentLength);
- break;
- case kMovieContent:
- AddMovieContent(spoolSpec,blockIndex,bodyBuffer,kMaxBufferSize,&rawContentLength);
- break;
- }
- }
- }
- }
- if (err==kNoData)
- err = noErr;
-
- DisposPtrChk(bodyBuffer);
-
- return err;
- }
-
-
- OSErr AddTextContent(FSSpec *spoolSpec,unsigned long blockIndex,Ptr bodyBuffer,
- unsigned long bufferLength,unsigned long *rawContentLength)
- {
- OSErr err,err2;
- unsigned long startOffset,dataLength;
- char *lfBuffer,*removeTerm;
-
- startOffset = 0;
- do {
- dataLength = bufferLength-1; // leave room for trailing null
- err = GetFromSpool(spoolSpec,kTextContent,kContentCreator,blockIndex,bodyBuffer,
- &dataLength,startOffset);
- if ((err==noErr)||(err==kMoreData)) {
- bodyBuffer[dataLength] = '\0';
- AddLF(bodyBuffer,&lfBuffer); // allocates lfBuffer ptr
-
- removeTerm = lfBuffer;
- do {
- removeTerm = strstr(removeTerm,kMessageTerminator);
- if (removeTerm)
- removeTerm[2] = ','; // substitute all CRLF.CRLF with CRLF,CRLF since this is msg. terminator
- } while (removeTerm);
-
- if (*rawContentLength==0)
- err2 = SpoolToFile(spoolSpec,kRawContentType,kRawContentCreator,0,lfBuffer,strlen(lfBuffer));
- else
- err2 = AppendToSpool(spoolSpec,kRawContentType,kRawContentCreator,0,lfBuffer,strlen(lfBuffer));
- if (err2==noErr) {
- startOffset += dataLength;
- *rawContentLength += strlen(lfBuffer);
- }
- DisposPtrChk((Ptr)lfBuffer);
- }
- } while ((err2==noErr) && (err==kMoreData));
-
- if (err==noErr)
- err = err2;
-
- return err;
- }
-
-
- OSErr AddPictContent(FSSpec *spoolSpec,unsigned long blockIndex,Ptr bodyBuffer,
- unsigned long bufferLength,unsigned long *rawContentLength)
- {
- OSErr err;
- char *notSupported = "\015\012\015\012[ picture omitted ]\015\012\015\012";
-
- if (*rawContentLength==0)
- err = SpoolToFile(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- else
- err = AppendToSpool(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- if (err==noErr)
- *rawContentLength += strlen(notSupported);
- return err;
- }
-
-
- OSErr AddSoundContent(FSSpec *spoolSpec,unsigned long blockIndex,Ptr bodyBuffer,
- unsigned long bufferLength,unsigned long *rawContentLength)
- {
- OSErr err;
- char *notSupported = "\015\012\015\012[ sound omitted ]\015\012\015\012";
-
- if (*rawContentLength==0)
- err = SpoolToFile(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- else
- err = AppendToSpool(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- if (err==noErr)
- *rawContentLength += strlen(notSupported);
- return err;
- }
-
-
- OSErr AddStyledTextContent(FSSpec *spoolSpec,unsigned long blockIndex,Ptr bodyBuffer,
- unsigned long bufferLength,unsigned long *rawContentLength)
- {
- OSErr err;
- char *notSupported = "\015\012\015\012[ styled text omitted ]\015\012\015\012";
-
- if (*rawContentLength==0)
- err = SpoolToFile(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- else
- err = AppendToSpool(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- if (err==noErr)
- *rawContentLength += strlen(notSupported);
- return err;
- }
-
-
- OSErr AddMovieContent(FSSpec *spoolSpec,unsigned long blockIndex,Ptr bodyBuffer,
- unsigned long bufferLength,unsigned long *rawContentLength)
- {
- OSErr err;
- char *notSupported = "\015\012\015\012[ movie omitted ]\015\012\015\012";
-
- if (*rawContentLength==0)
- err = SpoolToFile(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- else
- err = AppendToSpool(spoolSpec,kRawContentType,kRawContentCreator,0,notSupported,strlen(notSupported));
- if (err==noErr)
- *rawContentLength += strlen(notSupported);
- return err;
- }
-
-